#include "CircleGeometry.h"
POCELAIN_NAMESPACE_BEGIN
CircleGeometry::CircleGeometry(
    Real radius,
    uint32_t segments,
    Real thetaStart,
    Real thetaLength)
    :radius(radius)
    ,segments(segments)
    ,thetaStart(thetaStart)
    ,thetaLength(thetaLength)
{
    segments = std::max<uint32_t>( 3, segments );

    // buffers
    std::vector<uint32_t> indices;
    std::vector<Real> vertices;
    std::vector<Real> normals;
    std::vector<Real> uvs;

    // helper variables
    Vector3 vertex ;
    Vector2 uv ;

    // center point

    vertices.push_back( 0);
    vertices.push_back( 0);
    vertices.push_back( 0);

    normals.push_back( 0);
    normals.push_back( 0);
    normals.push_back( 1 );
    uvs.push_back( 0.5);
    uvs.push_back( 0.5);

    for ( uint32_t s = 0, i = 3; s <= segments; s ++, i += 3 )
    {
        Real segment = thetaStart + Real(s) / segments * thetaLength;

        // vertex
        vertex.x = radius * std::cos( segment );
        vertex.y = radius * std::sin( segment );

        vertices.push_back(vertex.x);
        vertices.push_back(vertex.y);
        vertices.push_back(vertex.z);

        // normal
        normals.push_back( 0);
        normals.push_back( 0);
        normals.push_back( 1);

        // uvs
        uv.x = ( vertices[ i ] / radius + 1 ) / 2;
        uv.y = ( vertices[ i + 1 ] / radius + 1 ) / 2;

        uvs.push_back( uv.x);
        uvs.push_back( uv.y);
    }

    // indices
    for ( uint32_t i = 1; i <= segments; i ++ )
    {
        indices.push_back( i);
        indices.push_back( i + 1);
        indices.push_back( 0);
    }

    // build geometry
    this->setIndices(new UInt32BufferAttribute(indices,3));
    this->setAttribute( "position", new Float32BufferAttribute( vertices, 3 ) );
    this->setAttribute( "normal", new Float32BufferAttribute( normals, 3 ) );
    this->setAttribute( "uv", new Float32BufferAttribute( uvs, 2 ) );
}
POCELAIN_NAMESPACE_END
